<?php

require_once __DIR__ . '/vendor/autoload.php';

// 创建连接
$connection = new \PhpAmqpLib\Connection\AMQPStreamConnection(
    '192.168.50.10',
    5672,
    'guest',
    'guest'
);

// 建立信道
$channel = $connection->channel();

// 定义交换机，队列，路由名称
$exchangeName = 'exchangeTest';
$queueName = 'queueTest';
$routeKeyName = 'routeKeyTest';

/**
 * Note:               创建交换机
 * name         string 交换机名称
 * type         string 交换机类型（Exchange Type)，分别是 direct/fanout/topic
 * passive      bool   如果设置 true，队列存在则返回 OK，否则报错；
 *                     如果设置 false，存在返回 OK，不存在则自动创建
 * durable      bool   是否持久化，设置 false 存放在内存中，RabbitMQ 重启后丢失
 * auto_delete  bool   是否自动删除，当最后一个消费者断开连接后队列是否自动删除
 */
$channel->exchange_declare(
    $exchangeName,
    \PhpAmqpLib\Exchange\AMQPExchangeType::DIRECT,
    false,
    true,
    false
);

/**
 * Note:               创建队列
 * name         string 队列名称
 * passive      bool   如果设置 true，队列存在则返回 OK，否则报错；
 *                     如果设置 false，存在返回 OK，不存在则自动创建
 * durable      bool   是否持久化，设置 false 存放在内存中，RabbitMQ 重启后丢失
 * exclusive    bool   是否排他，设置 true，则队列只对当前连接有效，连接断开后自动删除
 * auto_delete  bool   是否自动删除，当最后一个消费者断开连接后队列是否自动删除
 */
$channel->queue_declare($queueName, false, true, false, false);

// 绑定队列和交换机和路由（绑定名称）
$channel->queue_bind($queueName, $exchangeName, $routeKeyName);

/**
 * Note:                创建AMQP消息类型
 * body          string 消息体
 * delivery_mode int    消息是否持久化
 *                      AMQPMessage::DELIVERY_MODE_NON_PERSISTENT  不持久化
 *                      AMQPMessage::DELIVERY_MODE_PERSISTENT      持久化
 */
$msg = new \PhpAmqpLib\Message\AMQPMessage(
    'Hello World !',
    ['delivery_mode' => \PhpAmqpLib\Message\AMQPMessage::DELIVERY_MODE_NON_PERSISTENT]
);

// 开启消息确认
$channel->confirm_select();

// 推送成功
$channel->set_ack_handler(function (\PhpAmqpLib\Message\AMQPMessage $msg) {
    echo "Message acked with content " . $msg->body . PHP_EOL;
});

// 推送失败
$channel->set_ack_handler(function (\PhpAmqpLib\Message\AMQPMessage $msg) {
    echo "Message nacked with content " . $msg->body . PHP_EOL;
});

$i = 1;

/**
 * Note: 发送消息
 * msg      AMQMessage  AMQP 消息内容
 * exchange string      交换机名称
 * route    string      队列名称
 */
$channel->basic_publish($msg, $exchangeName, $routeKeyName);

while ($i <= 11) {
    $msg = new \PhpAmqpLib\Message\AMQPMessage($i++, array('content_type' => 'text/plain'));
    $channel->basic_publish($msg, $exchangeName, $routeKeyName);
}

// 阻塞等待消息确认 （生产者 防止信息丢失）
$channel->wait_for_pending_acks();

$channel->close();
$connection->close();